package com.android_map_app.activities;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;

import org.json.JSONArray;
import org.json.JSONObject;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.android_map_app.R;
import com.android_map_app.data.ResultType;
import com.android_map_app.data.User;
import com.android_map_app.data.UserData;
import com.android_map_app.services.UpdateService;

public class DataActivity extends Activity {
	
	public static final int CHANGE_NAME = Menu.FIRST;
	public static final int CHANGE_PASSWORD = Menu.FIRST + 1;
	public static final int DELETE_GROUP = Menu.FIRST;
	static final int DIALOG_DELETE_ID = 8; //random nr
	static final int DIALOG_DELETE_ACCOUNT_ID = 9; //random nr
	private Location mLoc;
	private ListView mListView;
	private TextView mName;
	private TextView mIdCode;
	private TextView mActiveGroup;
	private TextView mLongitude;
	private TextView mLatitude;
	private String[] mGroups;
	private SharedPreferences mPrefs;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		setProgressBarIndeterminate(true);
		
		setContentView(R.layout.data);
		
		mPrefs = getSharedPreferences(MainActivity.USER_PREF, MODE_PRIVATE);
		mListView = (ListView) findViewById(R.id.data_list);
		mName = (TextView) findViewById(R.id.data_name);
		mIdCode = (TextView) findViewById(R.id.data_id);
		mActiveGroup = (TextView) findViewById(R.id.active_group_name);
		mLongitude = (TextView) findViewById(R.id.data_longitude);
		mLatitude = (TextView) findViewById(R.id.data_latitude);
		
		Button logoutButton = (Button) findViewById(R.id.logout_button);
		
		logoutButton.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				SharedPreferences.Editor editor = mPrefs.edit();
				editor.remove("username");
				editor.remove("password");
				editor.remove("idCode");
				editor.remove("activeGroup");
				editor.commit();
				stopService(new Intent(getApplicationContext(), UpdateService.class));
				startActivity(new Intent(getApplicationContext(), MainActivity.class));
			}
		});
		
		Button deleteButton = (Button) findViewById(R.id.delete_button);
		
		deleteButton.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				new SendAccountDelete().execute();
				
			}
		});
		
		User user = UserData.getInstance().getUser();
		mName.setText(mPrefs.getString("username", ""));
		mIdCode.setText(mPrefs.getString("idCode", ""));
		mActiveGroup.setText(mPrefs.getString("activeGroup", "None"));
		mLoc = user.getLocation();
		if (mLoc != null) {
			mLongitude.setText(String.valueOf(mLoc.getLongitude()));
			mLatitude.setText(String.valueOf(mLoc.getLatitude()));
		} else {
			mLongitude.setText(R.string.stringNone);
			mLatitude.setText(R.string.stringNone);
		}
		
		new FillGroups().execute();
		
		registerForContextMenu(mListView);
		
	}
	
	@Override
	public void onRestart() {
		super.onRestart();
		mName.setText(mPrefs.getString("username", ""));
		mIdCode.setText(mPrefs.getString("idCode", ""));
		mActiveGroup.setText(mPrefs.getString("activeGroup", "None"));
		mLoc = UserData.getInstance().getUser().getLocation();
		if (mLoc != null) {
			mLongitude.setText(String.valueOf(mLoc.getLongitude()));
			mLatitude.setText(String.valueOf(mLoc.getLatitude()));
		} else {
			mLongitude.setText(R.string.stringNone);
			mLatitude.setText(R.string.stringNone);
		}
		
		new FillGroups().execute();
		
		registerForContextMenu(mListView);
	}
	
	@Override
	public void onResume() {
		super.onRestart();
		mName.setText(mPrefs.getString("username", ""));
		mIdCode.setText(mPrefs.getString("idCode", ""));
		mActiveGroup.setText(mPrefs.getString("activeGroup", "None"));
		mLoc = UserData.getInstance().getUser().getLocation();
		if (mLoc != null) {
			mLongitude.setText(String.valueOf(mLoc.getLongitude()));
			mLatitude.setText(String.valueOf(mLoc.getLatitude()));
		} else {
			mLongitude.setText(R.string.stringNone);
			mLatitude.setText(R.string.stringNone);
		}
		
		new FillGroups().execute();
		
		registerForContextMenu(mListView);
	}
	
	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        boolean result = super.onCreateOptionsMenu(menu);
        menu.add(0, CHANGE_NAME, 0, R.string.change_name);
        menu.add(0, CHANGE_NAME + 1, 0, R.string.change_password);
        return result;
    }
	
	@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case CHANGE_NAME:
            startActivity(new Intent(getApplicationContext(), ChangeNameActivity.class));
            return true;
        case CHANGE_PASSWORD:
        	startActivity(new Intent(getApplicationContext(), ChangePasswordActivity.class));
        	return true;
        }
        return super.onOptionsItemSelected(item);
    }
	
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
	        ContextMenu.ContextMenuInfo menuInfo) {
	    super.onCreateContextMenu(menu, v, menuInfo);
	    menu.add(0, DELETE_GROUP, 0, R.string.delete_group);
	}
	
	@Override
	public boolean onContextItemSelected(MenuItem item) {
	    switch(item.getItemId()) {
	    case DELETE_GROUP:
	        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
	        new SendDeleteRequest().execute(mGroups[(int) info.id]);
	        return true;
	    }
	    return super.onContextItemSelected(item);
	}
	
	private String[] getOwnerGroups() {
		try {
			URL url = new URL("http://" + getBaseContext().getString(R.string.server_name)
					+ "/update?action=getOwnerGroups&idCode="
					+ mPrefs.getString("idCode", ""));
			BufferedReader br = new BufferedReader(
					new InputStreamReader(url.openStream()));
			JSONArray groups = (new JSONObject(br.readLine())).getJSONArray("groups");
			br.close();
			String[] result = new String[groups.length()];
			for (int i = 0; i < groups.length(); i++) result[i] = groups.get(i).toString();
			return result;
		} catch (Throwable e) {
			displayToast(e.getMessage());
			return null;
		}
	}
	
	private void displayToast(String message) {
		Toast toast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG);
		toast.setGravity(Gravity.CENTER_HORIZONTAL|Gravity.CENTER_VERTICAL, 0, 0);
		toast.show();
	}
	
	private class FillGroups extends AsyncTask<String, Integer, ResultType> {

		@Override
		protected ResultType doInBackground(String... params) {
			mGroups = getOwnerGroups();
			if (mGroups != null) return ResultType.SUCCESS;
			else {
				return ResultType.ERROR;
			}
		}
		
		@Override
		protected void onPreExecute() {
			setProgressBarIndeterminateVisibility(true);
		}
		
		@Override
		protected void onPostExecute(ResultType result) {
			super.onPostExecute(result);
			switch (result) {
			case SUCCESS:
				mListView.setAdapter(new ArrayAdapter<String>(getApplicationContext(), R.layout.grouplist_item, mGroups));
				setProgressBarIndeterminateVisibility(false);
				break;
			case ERROR:
				setProgressBarIndeterminateVisibility(false);
				displayToast("Connection error.");
				break;
			}
		}
	}
	
	private class SendDeleteRequest extends AsyncTask<String, Integer, ResultType> {
		@Override
		protected ResultType doInBackground(String... params) {
			ResultType result;
			try {
				URL url = new URL("http://" + getBaseContext().getString(R.string.server_name)
						+ "/deletegroup?groupName="
						+ params[0] + "&ownerID="
						+ mPrefs.getString("idCode", ""));
				BufferedReader br = new BufferedReader(
						new InputStreamReader(url.openStream()));
				String input = br.readLine();
				br.close();
				if (!input.equals("FAIL")) {
					if (mPrefs.getString("activeGroup", "").equals(params[0])) {
						SharedPreferences.Editor editor = mPrefs.edit();
						editor.remove("activeGroup");
						editor.commit();
					}
					result = ResultType.SUCCESS;
				} else {
					result = ResultType.WRONG;
				}
			} catch (Throwable e) {
				result = ResultType.ERROR;
			}
			return result;
		}
		
		@Override
		protected void onPreExecute() {
			showDialog(DIALOG_DELETE_ID);
		}
		@Override
		protected void onPostExecute(ResultType result) {
			super.onPostExecute(result);
			dismissDialog(DIALOG_DELETE_ID);
			switch (result) {
			case SUCCESS:
				displayToast("Group deleted");
				mActiveGroup.setText(mPrefs.getString("activeGroup", "None"));
				new FillGroups().execute();
				registerForContextMenu(mListView);
				break;
			case WRONG:
				displayToast("Nonexistant group (Are you a wizard?)");
				new FillGroups().execute();
				registerForContextMenu(mListView);
				break;
			case ERROR:
				displayToast("Connection error.");
				break;
			}
		}
	}
	
	private class SendAccountDelete extends AsyncTask<String, Integer, ResultType> {
		@Override
		protected ResultType doInBackground(String... params) {
			ResultType result;
			try {
				URL url = new URL("http://" + getBaseContext().getString(R.string.server_name)
						+ "/update?action=deleteMember&idCode="
						+ mPrefs.getString("idCode", ""));
				BufferedReader br = new BufferedReader(
						new InputStreamReader(url.openStream()));
				String input = br.readLine();
				br.close();
				if (!input.equals("FAIL")) {
					SharedPreferences.Editor editor = mPrefs.edit();
					editor.remove("username");
					editor.remove("password");
					editor.remove("idCode");
					editor.remove("activeGroup");
					editor.commit();
					result = ResultType.SUCCESS;
				} else {
					result = ResultType.WRONG;
				}
			} catch (Throwable e) {
				result = ResultType.ERROR;
			}
			return result;
		}
		
		@Override
		protected void onPreExecute() {
			showDialog(DIALOG_DELETE_ACCOUNT_ID);
		}
		@Override
		protected void onPostExecute(ResultType result) {
			super.onPostExecute(result);
			dismissDialog(DIALOG_DELETE_ACCOUNT_ID);
			switch (result) {
			case SUCCESS:
				displayToast("Account deleted");
				stopService(new Intent(getApplicationContext(), UpdateService.class));
				startActivity(new Intent(getApplicationContext(), MainActivity.class));
				break;
			case WRONG:
				displayToast("Nonexistant account (Are you a wizard?)");
				break;
			case ERROR:
				displayToast("Connection error.");
				break;
			}
		}
	}
	
	@Override
	protected Dialog onCreateDialog(int id) {
		ProgressDialog dialog;
		switch (id) {
		case DIALOG_DELETE_ID:
			dialog = new ProgressDialog(this);
			dialog.setMessage(DataActivity.this.getString(R.string.stringDeleteGroupWait));
			dialog.setIndeterminate(true);
			dialog.setCancelable(true);
			return dialog;
		case DIALOG_DELETE_ACCOUNT_ID:
			dialog = new ProgressDialog(this);
			dialog.setMessage(DataActivity.this.getString(R.string.stringDeleteAccountWait));
			dialog.setIndeterminate(true);
			dialog.setCancelable(true);
			return dialog;
		}
		return null;
	}
}
